//
//  Battle.m
//  PacIsBack
//
//  Created by Simon André on 28/01/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "Battle.h"
#import "CharacterProtocol.h"
#import "AbilityProtocol.h"
#import "Game.h"


@implementation Battle

@synthesize game, playerTeam, player, ennemyTeam, controller, areaType, selectedCharacter, selectedAbility, charactersThatAlreadyActed, characterActionOrder;

-(id) initBattleWithPlayer:(id<PlayerProtocol>) thePlayer forGame:(Game*) theGame{
	if (self = [super init]) {
		[self setPlayer:thePlayer];
		[self setGame:theGame];
		[self setPlayerTeam:[[self player] battleTeam]];
		[[self playerTeam] setCurrentBattle:self];
		[self setAreaType:[[self player] currentArea]];
		[self setEnnemyTeam:[[self areaType] ennemyEncounter:[[[[self playerTeam] characters] objectAtIndex:0] level]]];
		[[self ennemyTeam] setCurrentBattle:self];
		BattleViewController* initController = [[BattleViewController alloc] initForModel:self];
		[self setController:initController];
		[initController release];
	}
	return self;
}

-(NSString*) musicType{
	return [[self areaType] battleMusic];
}

-(NSString*) background{
	return [[self areaType] battleBackground];
}

-(BOOL) isSelected:(id<CharacterProtocol>)character{
	return character==[self selectedCharacter];
}

-(void) executeCurrentActionNextPhase{
	[[self selectedAbility] nextPhase];
}

-(void) processCurrentActionFrom:(id<CharacterProtocol>) origin on:(id<CharacterProtocol>) target{
	[[self selectedAbility] executeFrom:origin on:target inBatte:self];
}

-(void) trySelecting:(id<CharacterProtocol>)character{
	if ([[[self playerTeam] characters] containsObject:character] && [[self characterActionOrder] objectAtIndex:0]==character) {
		if ([self selectedCharacter] != nil) {
			[[self selectedCharacter] unselect];
		}
		[self setSelectedCharacter:character];
		[character select];
		[[self controller] performSelectorOnMainThread:@selector(showAbilityAreaOfCharacter:) withObject:[self selectedCharacter] waitUntilDone:NO];
	}
	else {
		if ([[[self ennemyTeam] characters] containsObject:character]) {
			if ([self selectedCharacter] != nil) {
				[self processCurrentActionFrom:[self selectedCharacter] on:character];
				//[[self controller] executeAttackFrom:[self selectedCharacter] toTarget:character];
				[[self selectedCharacter] unselect];
				[self setSelectedCharacter:nil];[[self controller] performSelectorOnMainThread:@selector(removeAbilityArea) withObject:nil waitUntilDone:NO];
			}
		}
	}
}

-(NSInteger) inflictDamageFrom:(id<CharacterProtocol>) origin toTarget:(id<CharacterProtocol>) target{
	//NSInteger originAttackPower = [origin attackPower];
	//NSInteger inflictedDamages = [target receiveAttack:originAttackPower];
	return [[self selectedAbility] damagesProduced:origin on:target];
}

-(void) initBattleLoop{
	NSMutableArray* arrayOrdered = [[NSMutableArray alloc] init];
	NSArray* arrayPlayer = [[self playerTeam] characters];
	for (id<CharacterProtocol> charact in arrayPlayer) {
		[arrayOrdered addObject:charact];
	}
	NSArray* arrayEnnemy = [[self ennemyTeam] characters];
	for (id<CharacterProtocol> charact in arrayEnnemy) {
		[arrayOrdered addObject:charact];
	}
	[[self charactersThatAlreadyActed] sortUsingSelector:@selector(isFasterThan)];	
	[self setCharacterActionOrder:arrayOrdered];
	[arrayOrdered release];
	[self setCharactersThatAlreadyActed:[[[NSMutableArray alloc] init] autorelease]];
}

-(void) processEndOfFight{
	if (![[self playerTeam] isAlive]) {
		[[self ennemyTeam] obtainVictoryAgainst:[self playerTeam]];
	}
	else {
		[[self playerTeam] obtainVictoryAgainst:[self ennemyTeam]];
	}
}

-(void) goToNextEventAfterFightEnd{
	if (![[self playerTeam] isAlive]) {
		[[self game] fightLost:self];
	}
	else {
		[[self game] fightWon:self];
	}
}

-(void) battleLoop{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[self initBattleLoop];
	while ([[self ennemyTeam] isAlive] && [[self playerTeam] isAlive]) {
		[self trySelecting:[[self characterActionOrder] objectAtIndex:0]];
		BOOL turnInvalidated = NO;
		id<CharacterProtocol> currentChar = [[self characterActionOrder] objectAtIndex:0];
		if ([[self characterActionOrder] count] > 1) {
			id<CharacterProtocol> nextChar = [[self characterActionOrder] objectAtIndex:1];
			if ([nextChar speed] > [currentChar speed]) {
				[[self characterActionOrder] removeObjectAtIndex:0];
				[[self characterActionOrder] removeObjectAtIndex:0];
				[[self characterActionOrder] insertObject:currentChar atIndex:0];
				[[self characterActionOrder] insertObject:nextChar atIndex:0];
				turnInvalidated = YES;
			}
		}
		if (!turnInvalidated) {
			if (![currentChar isAlive]) {
				[[self characterActionOrder] removeObjectAtIndex:0];
			}
			else {
				[currentChar regenerationTick];
				[currentChar doAction];
				[[self characterActionOrder] removeObjectAtIndex:0];
				[[self charactersThatAlreadyActed] addObject:currentChar];
				[[self charactersThatAlreadyActed] sortUsingSelector:@selector(isFasterThan:)];
			}
		}
		if ([[self characterActionOrder] count] <= 0) {
			[self setCharacterActionOrder:[self charactersThatAlreadyActed]];
			[self setCharactersThatAlreadyActed:[[[NSMutableArray alloc] init] autorelease]];
		}
	}
	if (![[self playerTeam] isAlive]) {
		[[self controller] defeat];
	}
	else {
		[[self controller] victory];
	}
	[pool release];
}

-(void) showInfo:(NSString*) info{
	[[self controller] showInfo:info];
}

- (void) dealloc{
	[self setGame:nil];
	[self setPlayerTeam:nil];
	[self setPlayer:nil];
	[self setEnnemyTeam:nil];
	[self setController:nil];
	[self setAreaType:nil];
	[self setSelectedCharacter:nil];
	[self setSelectedAbility:nil];
	[self setCharactersThatAlreadyActed:nil];
	[self setCharacterActionOrder:nil];
	[super dealloc];
}

@end
